package com.imooc.mq;


import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * @author liansen
 * @create 02-19-18:02
 */
@Configuration
public class RabbitMQSMSConfig {

    @Bean
    @Scope("prototype")
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        /**
         * 强制委托(Mandatory设为true: 如果交换机根据routing key找不到对应的队列, 就会将消息返还给生产者)
         * 设为false, 出现上述情况, 交换机会将消息丢弃
         * 如果不设置rabbitTemplate.setMandatory(true),
         * 那么即便消息没进入队列，也不会触发returnCallback回调方法;
         */
        rabbitTemplate.setMandatory(true);
        return rabbitTemplate;
    }

    //定义通配符工作模式的交换机名称
    public static final String SMS_EXCHANGE = "sms_exchange";

    //定义队列名称
    public static final String SMS_QUEUE = "sms_queue";

    //交换机和队列绑定的路由键
    public static final String ROUTING_KEY_SMS_SEND_LOGIN = "imooc.sms.login.send";

    //创建通配符工作模式的交换机
    @Bean(SMS_EXCHANGE)
    public Exchange exchange(){
        return ExchangeBuilder.topicExchange(SMS_EXCHANGE).durable(true).build();
    }

    //创建队列
    @Bean(SMS_QUEUE)
    public Queue queue(){
        return QueueBuilder.durable(SMS_QUEUE)
                .withArgument("x-max-length", 6) //队列长度为6
                .withArgument("x-dead-letter-exchange", RabbitmqDeadConfig.SMS_EXCHANGE_DEAD)
                .withArgument("x-dead-letter-routing-key", RabbitmqDeadConfig.ROUTING_KEY_SMS_DEAD)
                .withArgument("x-message-ttl", 10 * 1000)
                .build();
    }

    //定义队列绑定到交换机的关系
    @Bean
    public Binding smsBinding(){
        /**
         * String destination, 目的地名称
         * DestinationType destinationType, 目的地类型
         * String exchange, 交换机名称
         * String routingKey, 路由键
         * Map<String, Object> arguments map类型参数
         *
         * #代表0个或多个单词, 如果是*，则代表只能有一个单词
         */
        return new Binding(SMS_QUEUE, Binding.DestinationType.QUEUE, SMS_EXCHANGE, "imooc.sms.#", null);
    }
}
